package
{
	import flash.geom.Point;

	public class GestureUtils
	{
		public function GestureUtils()
		{
		}
		
		/**
		 *从众多点中找出关键点 
		 * @param stroke
		 * @param numPoints 关键点个数
		 * @return 
		 * 
		 */		
		public static function temporalSampling(stroke:Vector.<Number>,numPts:int = 16):Vector.<Number> {
			var _copy:Vector.<Point> = new Vector.<Point>();
			for(var i:int = 0 ; i <stroke.length;i+=2){
				_copy.push(new Point(stroke[i],stroke[i+1]));
			}
			var _length:Number = calcLength(_copy);
			var _simplified:Vector.<Point> = new Vector.<Point>();
			_simplified.push(_copy[0]);
			var _target_segment_length:Number = _length/numPts;
			
			var startIndex:uint = 1;
			var center:Point = new Point(_copy[0].x, _copy[0].y);
			var r:Number = _target_segment_length;
			var p1:Point;
			
			for (var n:uint=1; n < numPts; n++) {
				
				for ( i=startIndex; i<_copy.length; i++) {
					
					//var p1:Point = new Point(center.x, center.y);
					if (! p1) p1 = new Point(center.x, center.y);
					var p2:Point = _copy[i];
					var ip:Point;
					
					var dx:Number = p2.x - p1.x;
					var dy:Number = p2.y - p1.y;
					var a:Number = dx*dx + dy*dy;
					var b:Number = (dx*(p1.x-center.x)+dy*(p1.y-center.y))*2;
					var c:Number = (center.x*center.x)+(center.y*center.y)+(p1.x*p1.x)+(p1.y*p1.y)-((center.x*p1.x+center.y*p1.y)*2)-(r*r);
					
					var d:Number = b*b-4*a*c;
					
					if (d >= 0) {
						if (d > 0) {
							//two potential solutions:
							var u1:Number = (-b + Math.sqrt((b*b)-4*a*c))/(2*a);
							var u2:Number = (-b - Math.sqrt((b*b)-4*a*c))/(2*a);
							var i1_x:Number = p1.x + u1*(p2.x - p1.x);
							var i1_y:Number = p1.y + u1*(p2.y - p1.y);
							var i2_x:Number = p1.x + u2*(p2.x - p1.x);
							var i2_y:Number = p1.y + u2*(p2.y - p1.y);
							if (u1 >= 0 && u1 <= 1) ip = new Point(i1_x, i1_y);
							if (u2 >= 0 && u2 <= 1) ip = new Point(i2_x, i2_y);
						} else {
							//one solution at the tangent
							var u:Number = (-b)/(2*a);
							var i_x:Number = p1.x + u*(p2.x - p1.x);
							var i_y:Number = p1.y + u*(p2.y - p1.y);
							if (u >= 0 && u <= 1) ip = new Point(i_x, i_y);
						}
					}
					
					if (ip) {
						startIndex = i;
						center.x = ip.x;
						center.y = ip.y;
						_simplified.push(ip);
						ip = null;
						p1 = null;
						break;
					} else {
						p1 = new Point(p2.x, p2.y);
					}
					
				}
				
			}
			var vector:Vector.<Number> = new Vector.<Number>();
			for each (var p:Point in _simplified) 
			{
				vector.push(p.x);	
				vector.push(p.y);	
			}
			
			return vector;
		}
		
		private static function calcLength(_path:Vector.<Point>):Number {
			
			var _length:Number = 0;
			
			for (var i:uint=1; i<_path.length; i++) {
				_length += Point.distance(_path[int(i-1)], _path[i]);
			}
			
			return _length;
			
		}
		
		public static function rotate(points:Vector.<Number>, angle:Number):Vector.<Number> {
			var cos:Number = Math.cos(angle);
			var sin:Number = Math.sin(angle);
			var size:int = points.length;
			for (var i:int = 0; i < size; i += 2) {
				var x:Number = points[i] * cos - points[i + 1] * sin;
				var y:Number = points[i] * sin + points[i + 1] * cos;
				points[i] = x;
				points[i + 1] = y;
			}
			return points;
		}
		
		public static function translate(points:Vector.<Number>, dx:Number, dy:Number):Vector.<Number> {
			var size:int = points.length;
			for (var i:int = 0; i < size; i += 2) {
				points[i] += dx;
				points[i + 1] += dy;
			}
			return points;
		}
		
		public static function minimumCosineDistance(vector1:Vector.<Number>,vector2:Vector.<Number>):Number {
			var avgDistSquared	:Number = 0;
			var len:int = vector1.length;
			for (var i:uint = 0; i < len-1; i++) {
				var dx:Number = vector1[i]- vector2[i];
				var dy:Number = vector1[i+1]- vector2[i+1];
				var distSquared:Number = dx*dx + dy*dy;
				avgDistSquared += distSquared;
			}
			avgDistSquared /= len;
			return  Math.sqrt(avgDistSquared);
		}
		
		public static function squaredEuclideanDistance(vector1:Vector.<Number>,vector2:Vector.<Number>):Number {
			var squaredDistance:Number = 0;
			var size:int = vector1.length;
			for (var i:int = 0; i < size; i++) {
				var difference:Number = vector1[i] - vector2[i];
				squaredDistance += difference * difference;
			}
			return squaredDistance / size;
		}
	}
}